package org.domain.sisteste.session;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRPdfExporter;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

/**
 * 
 * @author hugoalexandre
 * 
 */
@Name("supportReport")
@AutoCreate
@Scope(ScopeType.APPLICATION)
@BypassInterceptors
public class SupportReport implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public void gerarRelatorio(String nomeRelatorio,
			Map<String, Object> parametrosRelatorio,
			Collection<?> dadosRelatorio) throws JRException {

		parametrosRelatorio.put("LOGO", getLogoPath());

		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		JasperPrint jasperPrint = construirRelatorio(nomeRelatorio,
				parametrosRelatorio, dadosRelatorio);
		inicializarParametrosExport(new JRPdfExporter(), jasperPrint, stream);
		try {
			prepararResponse(nomeRelatorio, stream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void inicializarParametrosExport(JRExporter exporter,
			JasperPrint jasperPrint, ByteArrayOutputStream stream)
			throws JRException {
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, stream);
		exporter.exportReport();
	}

	private void prepararResponse(String nomeRelatorio,
			ByteArrayOutputStream stream) throws IOException {
		HttpServletResponse response = (HttpServletResponse) FacesContext
				.getCurrentInstance().getExternalContext().getResponse();
		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition", "attachment; filename=\""
				+ nomeRelatorio + ".pdf");
		response.setContentLength(stream.size());
		ServletOutputStream flusher = response.getOutputStream();
		stream.writeTo(flusher);
		flusher.flush();
		flusher.close();
		FacesContext.getCurrentInstance().responseComplete();
		stream.close();
		stream = null;
	}

	private static JasperPrint construirRelatorio(String relatorioNome,
			Map<String, Object> parametros, Collection<?> listaRelatorio)
			throws JRException {

		ServletContext scontext = (ServletContext) FacesContext
				.getCurrentInstance().getExternalContext().getContext();
		InputStream stream = getStreamRelatorio(relatorioNome, scontext);

		if (stream instanceof BufferedInputStream) {
			stream = (BufferedInputStream) stream;
		} else if (stream instanceof ByteArrayInputStream) {
			stream = (ByteArrayInputStream) stream;
		}
		return JasperFillManager.fillReport(stream, parametros,
				new JRBeanCollectionDataSource(listaRelatorio));
	}

	private static InputStream getStreamRelatorio(String relatorioNome,
			ServletContext scontext) {
		StringBuilder sb = new StringBuilder();
		sb.append("/relatorio/");
		sb.append(relatorioNome);
		sb.append(".jasper");
		return scontext.getResourceAsStream(sb.toString());
	}

	protected String getLogoPath() {
		return getRealPath(File.separator + "images" + File.separator
				+ "logo.png");
	}

	protected String getRealPath(String localArquivo) {
		ServletContext request = (ServletContext) FacesContext
				.getCurrentInstance().getExternalContext().getContext();
		return request.getRealPath(localArquivo);
	}
}
